#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>


#include <encoding_manager.h>
#include <fonts_manager.h>


static EncodingOpr *g_ptEncodingOpr_all = NULL;



/// @brief 传入缓冲区头地址，获取文本文件编码格式
/// @param bufhead 
/// @return 返回结构体指针
PEncodingOpr GetEncodingFormatForTextFile(unsigned char *bufhead)
{
	PEncodingOpr ptmp = g_ptEncodingOpr_all;
    while (ptmp)
    {   
        if (ptmp->Support(bufhead))
        {
            return ptmp;
        }
        else
        {
            ptmp = ptmp->ptNext;
        }
    }
    return NULL;
}



int RegisterEncodingOpr(EncodingOpr *ptEncodingOpr)
{
    ptEncodingOpr->ptNext = g_ptEncodingOpr_all;
    g_ptEncodingOpr_all = ptEncodingOpr;
    return 0;
}



// 这里一定要先创建副本！否则一个FontOpr只能被加到一个EncodingOpr当中
int AddFontOprToEncodingOpr(PFontOpr ptFontOpr, PEncodingOpr ptEncodingOpr)
{
	PFontOpr ptFontOprCpy;
	
	if (!ptEncodingOpr || !ptFontOpr)
	{
		return -1;
	}
	else
	{
		ptFontOprCpy = malloc(sizeof(FontOpr));
		if (!ptFontOprCpy)
		{
			return -1;
		}
		else
		{
			memcpy(ptFontOprCpy, ptFontOpr, sizeof(FontOpr));
			ptFontOprCpy->ptNext = ptEncodingOpr->ptThisEncodingFormatCanShow;
			ptEncodingOpr->ptThisEncodingFormatCanShow = ptFontOprCpy;
			return 0;
		}		
	}
}



// 从ptEncodingOpr的ptThisEncodingFormatCanShow中删除ptFontOpr
int DelFontOprFrmEncoding(PEncodingOpr ptEncodingOpr, PFontOpr ptFontOpr)
{
    if (!ptEncodingOpr || !ptFontOpr) {
        return -1;
    }

    PFontOpr ptTmp = ptEncodingOpr->ptThisEncodingFormatCanShow;
    PFontOpr ptPre = NULL;

    while (ptTmp)
    {
        if (strcmp(ptTmp->name, ptFontOpr->name) == 0)
        {
            // 如果是头结点，直接修改头结点
            if (ptPre == NULL) {
                ptEncodingOpr->ptThisEncodingFormatCanShow = ptTmp->ptNext;
            } else { 
                // 如果是中间节点，更新前一个节点的 next 指针
                ptPre->ptNext = ptTmp->ptNext;
            }
            free(ptTmp);
            return 0; 
        }

        ptPre = ptTmp;
        ptTmp = ptTmp->ptNext;
    }
    return -1; 
}




void RegisterAllEncodingOpr(void)
{
    extern void RegisterUtf8(void);
    RegisterUtf8();
    
    extern void RegisterAsciiEncoding(void);
    RegisterAsciiEncoding();

    extern void RegisterUtf16LE(void);
    RegisterUtf16LE();

    extern void RegisterUtf16BE(void);
    RegisterUtf16BE();
}




void ShowAllEncodingOpr(void)
{
    PEncodingOpr ptmp = g_ptEncodingOpr_all;
    while (ptmp)
    {
        printf("EncodingOpr : %s\n", ptmp->name);
        ptmp = ptmp->ptNext;
    }
}


int SetSupportFontForAllEncodingOpr(void)
{
    int ret;

    extern int SetSupportFontForUtf8(void);
    ret = SetSupportFontForUtf8();
    if (ret)
    {
        printf("SetSupportFontForUtf8 \n");
        return -1;
    }

    extern int SetSupportFontForAscii(void);
    ret = SetSupportFontForAscii();
    if (ret)
    {
        printf("SetSupportFontForAscii \n");
        return -1;
    }

    return 0;
}


PEncodingOpr GetEncodingOprByName(char *name)
{
    PEncodingOpr ptmp = g_ptEncodingOpr_all;
    while (ptmp)
    {
        if (strcmp(name, ptmp->name) == 0)
        {
            return ptmp;
        }
        ptmp = ptmp->ptNext;
    }
    return NULL;
}